---
id: dbcontext-view
title: 9.12 视图操作
sidebar_label: 9.12 视图操作
---

## 9.12.1 关于视图

视图是数据库中非常重要的对象，是一张虚拟表，通过视图我们可以对结果进行筛选缓存，同时还能实现颗粒化权限控制，如控制指定行，指定列。

## 9.12.2 视图的使用

在 `Furion` 中实现视图的操作非常简单，只需要创建视图模型，并继承 `EntityNotKey` 基类即可。代码如下：

### 9.12.2.1 创建视图 `SQL`

```sql
CREATE VIEW V_Person AS
SELECT Id,Name,Age,Address FROM person
```

### 9.12.2.2 视图模型

```cs {5,10}
using Furion.DatabaseAccessor;

namespace Furion.Core
{
    public class V_Person : EntityNotKey
    {
        /// <summary>
        /// 配置视图名
        /// </summary>
        public V_Person() : base("V_Person")
        {
        }

        /// <summary>
        /// 主键Id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 住址
        /// </summary>
        public string Address { get; set; }
    }
}
```

:::important 视图名称

视图实体只需要继承 `EntityNotKey` 基类并编写无参构造函数继承 `base("视图名称")` 即可。

:::

## 9.12.3 视图使用

视图除了不能操作（写）以外，其他操作和表操作无异。

```cs
var vEntities = v_repository.Where(u => u.Id >10).ToList();
```

## 9.12.4 视图最佳读取方式 ✔

由于视图是虚拟表，不应该对其进行写操作，所以应该采用 `只读仓储初始化视图`：

```cs {11,13,16}
using Furion.Core;
using Furion.DatabaseAccessor;
using Furion.DynamicApiController;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Furion.Application.Persons
{
    public class FurionService : IDynamicApiController
    {
        private readonly IReadableRepository<V_Person> _readableRepository;

        public FurionService(IRepository<V_Person> repository)
        {
            // 初始化只读仓储
            _readableRepository = repository.Constraint<IReadableRepository<V_Person>>();
        }

        /// <summary>
        /// 读取视图
        /// </summary>
        /// <returns></returns>
        public async Task<List<V_Person>> GetVPerson()
        {
            var list = await _readableRepository.AsAsyncEnumerable();
            return list;
        }
    }
}
```

:::tip 小知识

通过 `.Constraint<TEntity,TDbContextLocator>` 方法可以将仓储约束为特定仓储，如只读仓储，可读可写仓储，只新增仓储等。

:::

## 9.12.5 反馈与建议

:::note 与我们交流

给 Furion 提 [Issue](https://gitee.com/dotnetchina/Furion/issues/new?issue)。

:::
